package cn.flying.cloud.system.org.service.impl;

import javax.annotation.Resource;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.flying.cloud.base.common.utils.Ft;
import cn.flying.cloud.base.common.vo.PageRequest;
import cn.flying.cloud.base.common.vo.PageResponse;
import cn.flying.cloud.base.common.vo.vue.TreeInfoVO;
import cn.flying.cloud.common.enums.SeqTypeEnum;
import cn.flying.cloud.common.enums.StatusEnum;
import cn.flying.cloud.system.log.service.SysSeqInfoService;
import cn.flying.cloud.system.org.entity.SysOrgInfo;
import cn.flying.cloud.system.org.mapper.SysOrgInfoMapper;
import cn.flying.cloud.system.org.service.SysOrgInfoService;
import cn.flying.cloud.system.vo.OrgInfoVO;

/**
 * <p>
 * 组织机构信息表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2024-04-02 13:06:35
 */
@Service
public class SysOrgInfoServiceImpl extends ServiceImpl<SysOrgInfoMapper, SysOrgInfo> implements SysOrgInfoService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private SysSeqInfoService sysSeqInfoService;

    /**
     * 分页查询组织机构信息表数据
     *
     * @param request
     * @return
     */
    @Override
    public PageResponse<SysOrgInfo> getPageList(PageRequest<SysOrgInfo> request) {
        SysOrgInfo param = request.getParam();
        LambdaQueryWrapper<SysOrgInfo> wrapper = getLambdaQueryWrapper(param);
        // wrapper TODO

        Page<SysOrgInfo> page = this.page(new Page<>(request.getPageNum(), request.getPageSize()), wrapper);
        return new PageResponse<>(page.getTotal(), (int) page.getCurrent(), page.getRecords());
    }

    /**
     * 构建查询对象
     *
     * @param param
     * @return
     */
    private LambdaQueryWrapper<SysOrgInfo> getLambdaQueryWrapper(SysOrgInfo param) {
        LambdaQueryWrapper<SysOrgInfo> wrapper = new LambdaQueryWrapper<>();
        if (param != null) {
            if (Ft.String.isNotBlank(param.getOrgId())) {
                wrapper.eq(SysOrgInfo::getOrgId, param.getOrgId());
            }
            if (Ft.String.isNotBlank(param.getParentId())) {
                wrapper.eq(SysOrgInfo::getParentId, param.getParentId());
            }
            if (Ft.String.isNotBlank(param.getStatus())) {
                wrapper.eq(SysOrgInfo::getStatus, param.getStatus());
            }
        }
        return wrapper;
    }

    /**
     * 列表查询组织机构信息表数据
     *
     * @param sysOrgInfo
     * @return
     */
    @Override
    public List<OrgInfoVO> getList(SysOrgInfo sysOrgInfo) {
        LambdaQueryWrapper<SysOrgInfo> wrapper = new LambdaQueryWrapper<>();
//        if (Ft.String.isNotBlank(sysOrgInfo.getOrgId())) {
//            wrapper.eq(SysOrgInfo::getParentId, sysOrgInfo.getOrgId());
//        }
        if (Ft.String.isNotBlank(sysOrgInfo.getStatus())) {
            wrapper.eq(SysOrgInfo::getStatus, sysOrgInfo.getStatus());
        }

        List<SysOrgInfo> list = this.list(wrapper);
        List<OrgInfoVO> infoVOS = list.stream().map(orgInfo -> {
            OrgInfoVO infoVO = new OrgInfoVO();
            Ft.BeanCopier.copy(orgInfo, infoVO);
            return infoVO;
        }).collect(Collectors.toList());
        String parentId = Ft.String.isNotBlank(sysOrgInfo.getOrgId()) ? sysOrgInfo.getOrgId() : "root";
        return setOrgInfoChildren(infoVOS, parentId);
    }

    /**
     * 赋值child
     *
     * @param list
     * @param parentId
     * @return
     */
    private List<OrgInfoVO> setOrgInfoChildren(List<OrgInfoVO> list, String parentId) {
        return list.stream()
                // 过滤父节点
                .filter(parent -> parent.getParentId().equals(parentId))
                // 把父节点children递归赋值成为子节点
                .map(child -> {
                    List<OrgInfoVO> temp = setOrgInfoChildren(list, child.getOrgId());
                    if (!CollectionUtils.isEmpty(temp)) {
                        child.setChildren(temp);
                    }
                    return child;
                }).collect(Collectors.toList());
    }


    /**
     * 查询所有的组织机构信息表数据（树形结构）
     *
     * @return
     */
    @Override
    public List<TreeInfoVO> getAllOrgList() {
        LambdaQueryWrapper<SysOrgInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysOrgInfo::getStatus, StatusEnum.STATUS_Y.getCode());
        List<SysOrgInfo> list = this.list(wrapper);
        Map<String, List<SysOrgInfo>> listMap = list.stream().collect(Collectors.groupingBy(SysOrgInfo::getParentId));
        return setTreeInfoChildren(listMap.get("root"), listMap);
    }

    /**
     * 迭代设置children
     *
     * @param list
     * @param listMap
     * @return
     */
    private List<TreeInfoVO> setTreeInfoChildren(List<SysOrgInfo> list, Map<String, List<SysOrgInfo>> listMap) {
        List<TreeInfoVO> infos = new ArrayList<>();
        list.forEach(sysOrgInfo -> {
            TreeInfoVO infoVO = new TreeInfoVO();
            infoVO.setId(sysOrgInfo.getOrgId());
            infoVO.setLabel(sysOrgInfo.getOrgName());

            List<SysOrgInfo> children = listMap.get(sysOrgInfo.getOrgId());
            if (CollectionUtils.isNotEmpty(children)) {
                infoVO.setChildren(setTreeInfoChildren(children, listMap));
            } else {
                infoVO.setChildren(new ArrayList<>());
            }
            infos.add(infoVO);
        });
        return infos;
    }

    /**
     * 查询组织机构信息表详情数据
     *
     * @param sysOrgInfo
     * @return
     */
    @Override
    public SysOrgInfo getOneObj(SysOrgInfo sysOrgInfo) {
        LambdaQueryWrapper<SysOrgInfo> wrapper = getLambdaQueryWrapper(sysOrgInfo);
        return this.getOne(wrapper);
    }


    /**
     * 新增组织机构信息表数据
     *
     * @param sysOrgInfo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean createObj(SysOrgInfo sysOrgInfo) {
        String orgId = sysSeqInfoService.getNextSeq(SeqTypeEnum.DEPT.name());
        sysOrgInfo.setOrgId(orgId);

        LambdaQueryWrapper<SysOrgInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysOrgInfo::getOrgId, sysOrgInfo.getParentId());
        SysOrgInfo parent = this.getOne(wrapper);
        sysOrgInfo.setOrgPath(parent.getOrgPath() + orgId + "/");
        return this.save(sysOrgInfo);
    }

    /**
     * 更新组织机构信息表数据
     *
     * @param sysOrgInfo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateObj(SysOrgInfo sysOrgInfo) {
        LambdaQueryWrapper<SysOrgInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysOrgInfo::getOrgId, sysOrgInfo.getParentId());
        SysOrgInfo parent = this.getOne(wrapper);
        sysOrgInfo.setOrgPath(parent.getOrgPath() + sysOrgInfo.getOrgId() + "/");
        return this.saveOrUpdate(sysOrgInfo);
    }

    /**
     * 删除组织机构信息表数据
     *
     * @param sysOrgInfo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteObj(SysOrgInfo sysOrgInfo) {
        LambdaQueryWrapper<SysOrgInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysOrgInfo::getOrgId, sysOrgInfo.getOrgId());
        return this.remove(wrapper);
    }

    /**
     * 根据Id删除
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteById(Serializable id) {
        return this.removeById(id);
    }
}
